package com.hnkywl.sts.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class XmlParse {
    private InterfaceParam interfaceParam;
    //Document可以看作是XML在内存中的一个镜像,那么一旦获取这个Document 就意味着可以通过对
    //内存的操作来实现对XML的操作,首先第一步获取XML相关的Document
    private Document doc = null;
    public static final String VCHRID = "vchrid";
    public static final String VCHRTYPE = "voucher_type";
    public static final String VCHRNUM = "u8voucher_id";
    public static final String U8_SUCCEED = "succeed";
    public static final String U8_ENTRY_ID = "entry_id";
    public static final String U8_DSC = "dsc";
    public static final String RESPONSEFLAG = "responseflag";
    public static final String RESPONSEMESSAGE = "responsemessage";

    public void init(String xml) throws Exception {
        //很明显该类是一个单例,先获取产生DocumentBuilder工厂
        //的工厂,在通过这个工厂产生一个DocumentBuilder,
        //DocumentBuilder就是用来产生Document的
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        //这个Document就是一个XML文件在内存中的镜像
        ByteArrayInputStream in = new ByteArrayInputStream(xml.getBytes());
        doc = db.parse(in);
    }

    public Map<String, String> getContent(String xml) {
        Map<String, String> result = new HashMap<String, String>();
        try {
            if (xml != null) {
                xml = xml.replaceAll("null", "");
                String regexEncoding = "encoding=[\"\'][\\w-]*[\"\']";
                String regexVersion = "xml version";
                if (!xml.matches(regexEncoding)) {
                    if (!xml.contains(regexVersion)) {
                        xml = "<?xml version=\"1.0\" encoding=\"" + interfaceParam.getXmlEncoding() + "\"?>" + xml;
                    } else {
                        xml = xml.replaceFirst("version=[\"\'][\\w.]*[\"\']",
                                "version=\"1.0\" encoding=\"" + interfaceParam.getXmlEncoding() + "\"");
                    }
                }
                if ("GBK".equals(interfaceParam.getXmlEncoding())) {
                    xml = xml.replaceFirst(regexEncoding, "encoding=\"GBK\"");
                    this.init(ConvertCharSet.toGBK(xml));
                }
                if ("UTF-8".equals(interfaceParam.getXmlEncoding())) {
                    xml = xml.replaceFirst(regexEncoding, "encoding=\"UTF-8\"");
                    this.init(ConvertCharSet.toUTF8(xml));
                }
            } else {
                result.put(XmlParse.RESPONSEFLAG, "0");
                result.put(XmlParse.RESPONSEMESSAGE, "U8财务接口无法访问，请稍后重试，或联系用友服务人员!");
                return result;
            }
//            String flag = getTextContent(XmlParse.RESPONSEFLAG);
//            String message = getTextContent(XmlParse.RESPONSEMESSAGE);
//            if (flag != null && "0".equals(flag)) {
//                result.put(XmlParse.RESPONSEFLAG, flag);
//                result.put(XmlParse.RESPONSEMESSAGE, message);
//            } else {
//                result.put(XmlParse.RESPONSEFLAG, flag);
//                result.put(XmlParse.RESPONSEMESSAGE, message);
//                String vchrid = getTextContent(XmlParse.VCHRID);
//                result.put(XmlParse.VCHRID, vchrid);
//                String vchrnum = getTextContent(XmlParse.VCHRNUM);
//                result.put(XmlParse.VCHRNUM, vchrnum);
//                String vchrtype = getTextContent(XmlParse.VCHRTYPE);
//                result.put(XmlParse.VCHRTYPE, vchrtype);
//            }
            String flag = getTagAttributeValue("item", XmlParse.U8_SUCCEED);
            if (flag != null && !"0".equals(flag)) {
                result.put(XmlParse.RESPONSEFLAG, "0");

                List<Map> messages = getTagAttributeValue("item", XmlParse.U8_ENTRY_ID, XmlParse.U8_DSC);
                StringBuilder message = new StringBuilder();
                for (int i = 0; i < messages.size(); i++) {
                    String entryId = (String) messages.get(i).get(XmlParse.U8_ENTRY_ID);
                    String dsc = (String) messages.get(i).get(XmlParse.U8_DSC);
                    if (!entryId.isEmpty())
                        message.append("第" + entryId + "分录：" + dsc);
                    else
                        message.append(dsc);
                    if (i != messages.size() - 1)
                        message.append(";");
                }
                result.put(XmlParse.RESPONSEMESSAGE, "【错误代码:" + flag + "】  " + message);
            } else {
                result.put(XmlParse.RESPONSEFLAG, "1");
                String message = getTagAttributeValue("item", XmlParse.U8_DSC);
                result.put(XmlParse.RESPONSEMESSAGE, message);
                String vchrid = "";
                result.put(XmlParse.VCHRID, vchrid);
                String vchrnum = getTagAttributeValue("item", XmlParse.VCHRNUM);
                result.put(XmlParse.VCHRNUM, vchrnum);
                String vchrtype = getTagAttributeValue("item", XmlParse.VCHRTYPE);
                result.put(XmlParse.VCHRTYPE, vchrtype);
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.put(XmlParse.RESPONSEFLAG, "0");
            result.put(XmlParse.RESPONSEMESSAGE, "返回的xml数据无法解析!" + e.getMessage());
        }
        return result;
    }

    public String getTextContent(String tag) {
        String temp = null;
        NodeList nodeList = doc.getElementsByTagName(tag);
        if (nodeList != null && nodeList.getLength() != 0) {
            Node responseFlag = nodeList.item(0);
            temp = responseFlag.getTextContent();
        }
        return temp;
    }

    public List<Map> getTagAttributeValue(String tag, String... attributeList) {
        List<Map> result = null;
        NamedNodeMap m = null;
        NodeList nodeList = doc.getElementsByTagName(tag);
        if (nodeList != null && nodeList.getLength() != 0) {
            result = new ArrayList<Map>();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Map<String, String> temp = new HashMap<String, String>();
                Node responseFlag = nodeList.item(i);
                m = responseFlag.getAttributes();
                for (String attribute : attributeList) {
                    Node node = m.getNamedItem(attribute);
                    temp.put(attribute, node.getNodeValue());
                }
                result.add(temp);
            }
        }
        return result;
    }

    public Map<String, String> getTagAttributeValue(String tag, Integer index, String... attributeList) {
        Map<String, String> result = null;
        NamedNodeMap m = null;
        NodeList nodeList = doc.getElementsByTagName(tag);
        if (nodeList != null && nodeList.getLength() > index && index >= 0) {
            result = new HashMap<String, String>();
            Node responseFlag = nodeList.item(index);
            m = responseFlag.getAttributes();
            for (String attribute : attributeList) {
                Node node = m.getNamedItem(attribute);
                result.put(attribute, node.getNodeValue());
            }
        }
        return result;
    }

    public String getTagAttributeValue(String tag, String attribute) {
        Map<String, String> result = getTagAttributeValue(tag, 0, attribute);
        return result.get(attribute);
    }

//    public static void main(String[] args) throws Exception {
//        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " +
//                "<response> " +
//                "  <id>1a3c7797ec214532907a7551176608a8</id> " +
//                "  <responseflag a='1'>1</responseflag> " +
//                "  <responsemessage>生成凭证成功</responsemessage> " +
//                "  <voucherinfo> " +
//                "   <vchrid>3D3EADE220000001651478829E373B26</vchrid> " +
//                "   <vchrnum>39</vchrnum> " +
//                "   <vchrtype>银行</vchrtype> " +
//                "  </voucherinfo> " +
//                " </response>";
//        XmlParse parse = new XmlParse();
//        InterfaceParam p = new InterfaceParam();
//        p.setXmlEncoding("UTF-8");
//        parse.setInterfaceParam(p);
//        //我的XML文件
//        Map m = parse.getContent(xml);
//        System.out.print("");
//    }

    @Autowired
    public void setInterfaceParam(InterfaceParam interfaceParam) {
        this.interfaceParam = interfaceParam;
    }
}
